package com.coai.gateway.filter

import com.coai.gateway.security.JwtTokenProvider
import org.springframework.cloud.gateway.filter.GatewayFilter
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory
import org.springframework.http.HttpStatus
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.stereotype.Component
import org.springframework.web.server.ServerWebExchange

/**
 * JWT认证过滤器
 */
@Component
class AuthenticationFilter(
    private val jwtTokenProvider: JwtTokenProvider
) : AbstractGatewayFilterFactory<AuthenticationFilter.Config>(Config::class.java) {
    
    override fun apply(config: Config): GatewayFilter {
        return GatewayFilter { exchange, chain ->
            val request = exchange.request
            
            // 公开路径不需要认证
            if (isPublicPath(request.path.value())) {
                return@GatewayFilter chain.filter(exchange)
            }
            
            // 提取token
            val token = extractToken(request)
            
            if (token == null) {
                exchange.response.statusCode = HttpStatus.UNAUTHORIZED
                return@GatewayFilter exchange.response.setComplete()
            }
            
            // 验证token
            if (!jwtTokenProvider.validateToken(token)) {
                exchange.response.statusCode = HttpStatus.UNAUTHORIZED
                return@GatewayFilter exchange.response.setComplete()
            }
            
            // 提取用户ID并添加到请求头
            val userId = jwtTokenProvider.getUserIdFromToken(token)
            val mutatedRequest = exchange.request.mutate()
                .header("X-User-Id", userId)
                .build()
            
            val mutatedExchange = exchange.mutate()
                .request(mutatedRequest)
                .build()
            
            chain.filter(mutatedExchange)
        }
    }
    
    private fun isPublicPath(path: String): Boolean {
        val publicPaths = listOf(
            "/api/users/register",
            "/api/users/login",
            "/ws",
            "/rtc-ws"
        )
        
        return publicPaths.any { path.startsWith(it) }
    }
    
    private fun extractToken(request: ServerHttpRequest): String? {
        val authHeader = request.headers.getFirst("Authorization")
        return if (authHeader != null && authHeader.startsWith("Bearer ")) {
            authHeader.substring(7)
        } else {
            null
        }
    }
    
    class Config
}
